import { Device, GatewayType } from "@/api/interface/iot";
import { getDeviceListAll } from "@/api/modules/iot/device";
import { changeGroup, modifyGateway, removeGateway, saveToProduct, syncGateway, syncGetGateway } from "@/api/modules/iot/gateway";
import { serviceStart, serviceStop } from "@/api/modules/service/service";
import DialogBox from "@/components/DialogBox";
import Empty from "@/components/Empty";
import BaseMap from "@/components/Map/antvl7/BaseMap";
import ProTable from "@/components/ProTable/index.vue";
import { ColumnProps } from "@/components/ProTable/interface";
import DeptTree from "@/components/Sansan/DeptTree";
import SelectDeptList from "@/components/Sansan/SelectDeptList";
import OnlineStatus from "@/components/Sansan/Status/OnlineStatus";
import BaseSearchForm from "@/components/SearchForm/BaseSearchForm";
import { MessageType } from "@/enums/messageEnum";
import { RouterPath } from "@/enums/routerPath";
import { DeviceStatusEnum, DeviceType } from "@/enums/statusEnum";
import { useAddress } from "@/hooks/useAddress";
import { useAuthButtonList, useAuthButtons } from "@/hooks/useAuthButtons";
import { dataFormat, isRootDeptId } from "@/utils/format";
import { gotoPage } from "@/utils/routerUtil";
import { confirm, showMsg, showTips } from "@/utils/util";
import { useRouter } from "vue-router";
import SaveToProduct from "../product/components/SaveToProduct";
import BasicDialog from "./components/basicInfo/basicDialog";
import { ComponentInternalInstance, getCurrentInstance } from "vue";
import { devTaskAdd } from "@/api/modules/system/devTask";
import DevUpgradeDialog from "@/views/system/devMaintenance/devUpgrade/components/detailDialog";
import DevConfigDialog from "@/views/system/devMaintenance/devConfig/components/detailDialog";
import DevRestartDialog from "@/views/system/devMaintenance/devRestart/components/detailDialog";
export default defineComponent({
	name: "SoftGatewayList",
	setup() {
		const { proxy } = getCurrentInstance() as ComponentInternalInstance;
		const router = useRouter();
		const initParam = reactive<Device.ReqGateway>({ typeNot: "device" });

		const dataCallback = (data: any) => {
			return {
				datalist: data.records,
				total: data.total,
				pageIndex: data.current,
				pageSize: data.size
			};
		};

		const getTableList = async (params: any) => {
			// return { result: { records: [{}, {}] } };
			return getDeviceListAll(params);
		};
		const buttonsList = ref<any>([]);
		const btnOperateList = ref<any>([]);
		onMounted(async () => {
			useAuthButtonList().then(btnList => {
				btnOperateList.value = btnList.filter((item: any) => item.type == "operate");
			});
			// 获取页面按钮权限
			let btnList = await useAuthButtons();
			buttonsList.value = btnList.filter((item: any) => !item.btnGroup || item.btnGroup != 3);
		});
		onActivated(() => {
			proTable.value.getTableList();
		});
		// buttonsList.value = [
		// 	{
		// 		text: "添加",
		// 		component: "add",
		// 		type: "primary"
		// 	}
		// ];
		const addDialog = reactive<any>({
			title: proxy?.$t("gateway.diolog_title.add"),
			visible: false,
			detail: {}
		});
		const clickBtn = async (fn: string, scope: any) => {
			let selectList = scope?.row ? [scope?.row] : scope?.selectList || [];
			switch (fn) {
				case "assignGroup":
					if (!selectList.length) {
						showMsg(proxy?.$t("gateway.msg.assignGroup"), MessageType.warning);
						return;
					}
					assignGroupDialog.detail.selectList = selectList;
					assignGroupDialog.visible = true;
					break;
				case "updateLocation":
					if (selectList.length != 1) {
						showMsg(proxy?.$t("gateway.msg.updateLocation"), MessageType.warning);
						return;
					}
					updateLocationDialog.detail = { ...(selectList[0] || {}) };
					updateLocationDialog.visible = true;
					break;
				case "mod":
					if (selectList.length != 1) {
						showMsg(proxy?.$t("gateway.msg.mod"), MessageType.warning);
						return;
					}
					if (isRootDeptId(selectList, true)) return;
					addDialog.visible = true;
					addDialog.detail = selectList[0];
					break;
				case "details":
					router.push({
						path: RouterPath.gatewayDetail,
						query: { sn: selectList[0].sn, type: selectList[0].type, menuId: selectList[0].type }
					});
					break;
				case "sync":
					if (selectList.length != 1) {
						showMsg(proxy?.$t("gateway.msg.sync"), MessageType.warning);
						return;
					}
					syncGateway({ idSn: selectList.map((item: any) => item.sn).join(",") }, selectList[0].type).then(res => {
						showTips(res.code, proxy?.$t("gateway.tips.sync"), res.message);
					});
					break;
				case "syncGet":
					//需要等待同步响应，不支持批量下发
					selectList.forEach((item: any) => {
						syncGetGateway({ idSn: item.sn });
					});
					showMsg(proxy?.$t("gateway.msg.syncGet"));
					break;
				case "add":
					// initGatewayDetail();
					addDialog.detail = { location: {}, type: "" };
					addDialog.visible = true;
					break;
				case "del":
					if (isRootDeptId(selectList, true)) return;
					confirm({ content: proxy?.$t("gateway.confirm.del") }).then(flag => {
						flag && submitDel({ idSn: selectList.map((item: any) => item.sn).toString() });
					});
					break;
				case "stop":
					if (selectList.length != 1) {
						showMsg(proxy?.$t("gateway.msg.stop"), MessageType.warning);
						return;
					}
					serviceStop({ instanceId: `${selectList[0].sn}.${selectList[0].sn}.SSIOT-MASTER` }).then(res => {
						showTips(res.code, proxy?.$t("gateway.tips.stop"), res.message) && proTable.value.getTableList();
					});
					break;
				case "start":
					if (selectList.length != 1) {
						showMsg(proxy?.$t("gateway.msg.start"), false);
						return;
					}
					serviceStart({ instanceId: `${selectList[0].sn}.${selectList[0].sn}.SSIOT-MASTER` }).then(res => {
						showTips(res.code, proxy?.$t("gateway.tips.start"), res.message) && proTable.value.getTableList();
					});
					break;
				case "saveToProduct":
					if (selectList.length != 1) {
						showMsg(proxy?.$t("gateway.msg.saveToProduct"), MessageType.warning);
						return;
					}
					saveToProductDialog.formData.id = selectList[0].sn;
					saveToProductDialog.formData.name = selectList[0].name;
					saveToProductDialog.formData.type = selectList[0].type;
					saveToProductDialog.visible = true;
					break;
				case "devUpgrade":
					if (!selectList.length) {
						showMsg(proxy?.$t("device.btnmsg.assignGroup"), MessageType.warning);
						return;
					}
					detailDialog.detail = {};
					detailDialog.visibleUpgrade = true;
					detailDialog.selectList = selectList;
					break;
				case "devConfig":
					if (!selectList.length) {
						showMsg(proxy?.$t("device.btnmsg.assignGroup"), MessageType.warning);
						return;
					}
					detailDialog.detail = {};
					detailDialog.visibleConfig = true;
					detailDialog.selectList = selectList;
					break;
				case "devRestart":
					if (!selectList.length) {
						showMsg(proxy?.$t("device.btnmsg.assignGroup"), MessageType.warning);
						return;
					}
					detailDialog.detail = {};
					detailDialog.visibleRestart = true;
					detailDialog.selectList = selectList;
					break;
			}
		};
		const detailDialog = reactive<any>({
			title: "新增任务",
			detail: {},
			visibleUpgrade: false,
			visibleConfig: false,
			visibleRestart: false,
			selectList: []
		});
		const submitTask = async (taskType: any, visible?: any) => {
			detailDialog.detail.filters = { sns: detailDialog.selectList.map((item: any) => item.sn).toString() };
			let res = await devTaskAdd({ ...detailDialog.detail, taskType: taskType });
			let ok = showTips(res.code, "任务创建", res.message);
			if (ok && visible) {
				detailDialog[visible] = false;
				console.log(detailDialog.detail.switchVal);
				console.log(taskType);
				if (detailDialog.detail.switchVal) {
					switch (taskType) {
						case "restart":
							gotoPage(RouterPath.devRestart);
							break;
						case "upgrade":
							gotoPage(RouterPath.devUpgrade);
							break;
						case "config":
							gotoPage(RouterPath.devConfig);
							break;
					}
				}
			}
		};
		// 表格配置项
		const columns: ColumnProps[] = [
			{ type: "selection", fixed: "left", width: "auto" },
			{ prop: "onlineStatus", label: proxy?.$t("gateway.tablist_label.onlineStatus"), width: 80, search: { slot: {} } },
			{ prop: "name", label: proxy?.$t("gateway.tablist_label.name"), width: 180, search: { el: "input" } },
			{ prop: "sn", label: proxy?.$t("gateway.tablist_label.sn"), width: 180, search: { el: "input" } },
			{ prop: "deptName", label: proxy?.$t("gateway.tablist_label.deptName"), width: "120", search: { slot: {} } },
			{ prop: "lastLiveTime", label: proxy?.$t("gateway.tablist_label.lastLiveTime"), width: 170 },
			{ prop: "logoutTime", label: proxy?.$t("gateway.tablist_label.logoutTime"), width: 170 },
			{ prop: "productModel", label: proxy?.$t("gateway.tablist_label.productModel"), width: 170 },
			{ prop: "type", label: proxy?.$t("gateway.tablist_label.type"), width: 170 },
			{ prop: "location", label: proxy?.$t("gateway.tablist_label.location") },
			{ prop: "operation", label: proxy?.$t("gateway.tablist_label.operation"), fixed: "right", width: 130 }
		];
		const assignGroupDialog = reactive<any>({
			visible: false,
			title: proxy?.$t("gateway.diolog_title.assign_group"),
			detail: {
				selectList: [],
				deptId: "",
				deptName: ""
			}
		});
		//调整分组
		const submitAssignGroup = async () => {
			let { code, message } = await changeGroup(
				{
					idSn: assignGroupDialog.detail.selectList.map((item: any) => item.id).toString(),
					deptId: assignGroupDialog.detail.deptId
				},
				GatewayType.Gateway
			);
			let ok = showTips(code, proxy?.$t("gateway.tips.assign_group"), message);
			if (ok) {
				assignGroupDialog.visible = false;
				proTable.value.getTableList();
			}
		};
		const proTable = ref<any>();
		const submitDel = async (dataInfo: any) => {
			let res = await removeGateway({ ...dataInfo }, GatewayType.Gateway);
			let ok = showTips(res.code, proxy?.$t("gateway.tips.del"), res.message);
			if (ok) {
				proTable.value.clearSelection();
				proTable.value.reset();
			}
		};
		const submitAdd = (ok: boolean) => {
			if (ok) {
				addDialog.visible = false;
				proTable.value.clearSelection();
				proTable.value.getTableList();
			}
		};
		const saveToProductDialog = reactive<any>({
			visible: false,
			formData: {
				id: "",
				name: "",
				type: GatewayType.Device
			}
		});

		const submitToProduct = async (data: Device.ReqProduct) => {
			data.idSn = data.id;
			let { code, message } = await saveToProduct(data, data.deviceType);
			let ok = showTips(code, proxy?.$t("gateway.tips.save_to_product"), message);
			if (ok) saveToProductDialog.visible = false;
		};

		//由use hooks中进行回调（不同类型网关的GatewayType不一样）
		const updateGatewayInfo = async (data: any) => {
			return modifyGateway(data, data.type);
		};
		const collapsedSearch = ref<boolean>(false);
		const { updateLocationDialog, submitLocation } = useAddress(updateGatewayInfo, proTable);
		return () => {
			return (
				<div>
					<DevUpgradeDialog
						width="600px"
						title={detailDialog.title}
						v-model:visible={detailDialog.visibleUpgrade}
						detail={detailDialog.detail}
						onSubmit={() => submitTask("upgrade", "visibleUpgrade")}
					></DevUpgradeDialog>
					<DevConfigDialog
						width="600px"
						title={detailDialog.title}
						v-model:visible={detailDialog.visibleConfig}
						detail={detailDialog.detail}
						onSubmit={() => submitTask("config", "visibleConfig")}
					></DevConfigDialog>
					<DevRestartDialog
						width="600px"
						title={detailDialog.title}
						v-model:visible={detailDialog.visibleRestart}
						detail={detailDialog.detail}
						onSubmit={() => submitTask("restart", "visibleRestart")}
					></DevRestartDialog>
					<SaveToProduct
						title={proxy?.$t("gateway.diolog_title.save_to_product")}
						v-model:visible={saveToProductDialog.visible}
						formData={saveToProductDialog.formData}
						width="600px"
						onSubmit={(data: Device.ReqProduct) => {
							submitToProduct(data);
						}}
					></SaveToProduct>
					<DialogBox
						class="dialog-dense"
						title={assignGroupDialog.title}
						v-model:visible={assignGroupDialog.visible}
						width="500px"
					>
						<DeptTree detail={assignGroupDialog.detail} onChange={() => submitAssignGroup()} class="p-8 assign-group" />
					</DialogBox>
					<BasicDialog
						width="700px"
						title={addDialog.detail.id ? proxy?.$t("gateway.basic_diolog_title.edit") : addDialog.title}
						v-model:visible={addDialog.visible}
						detail={addDialog.detail}
						onSubmit={(ok: boolean) => submitAdd(ok)}
					></BasicDialog>
					<DialogBox
						class="dialog-dense"
						title={updateLocationDialog.title}
						v-model:visible={updateLocationDialog.visible}
						onConfirm={() => submitLocation()}
					>
						{updateLocationDialog.visible ? (
							<BaseMap style="height:50vh" editerMarker detail={updateLocationDialog.detail} />
						) : null}
						<div class="address-detail">{updateLocationDialog.detail.location?.address}</div>
					</DialogBox>
					{collapsedSearch.value ? null : (
						<BaseSearchForm class="mb-2">
							<el-form
								class="flex pt-4 pl-4 pr-4 bg-white"
								style="flex-wrap: wrap;"
								onKeyup={(e: KeyboardEvent) => (e.keyCode == 13 ? proTable.value.getTableList() : null)}
							>
								<el-form-item class="search-item" label={proxy?.$t("gateway.search_label.deptName")}>
									<div style="width:180px">
										<SelectDeptList detail={initParam} appendChild />
									</div>
								</el-form-item>
								<el-form-item class="search-item" label={proxy?.$t("gateway.search_label.name")}>
									<el-input
										v-model={initParam.name}
										placeholder={proxy?.$t("gateway.search_placeholder.name")}
										style="width:130px"
									/>
								</el-form-item>
								<el-form-item class="search-item" label={proxy?.$t("gateway.search_label.sn")}>
									<el-input v-model={initParam.sn} placeholder={proxy?.$t("gateway.search_placeholder.sn")} style="width:130px" />
								</el-form-item>
								<el-form-item class="search-item" label={proxy?.$t("gateway.search_label.productModel")}>
									<el-input
										v-model={initParam.productModel}
										placeholder={proxy?.$t("gateway.search_placeholder.productModel")}
										style="width:130px"
									/>
								</el-form-item>
								<el-form-item class="search-item" label={proxy?.$t("gateway.search_label.onlineStatus")}>
									<el-select v-model={initParam.onlineStatus} style="width:100px">
										<el-option label={proxy?.$t("gateway.status_option.all")} value=""></el-option>
										<el-option label={proxy?.$t("gateway.status_option.online")} value={DeviceStatusEnum.ONLINE}></el-option>
										<el-option label={proxy?.$t("gateway.status_option.offline")} value={DeviceStatusEnum.OFFLINE}></el-option>
									</el-select>
								</el-form-item>
								<el-form-item class="search-item">
									<el-button type="primary" class="iconfont iconsearch" onClick={() => proTable.value.getTableList()}>
										{proxy?.$t("common.btn.search")}
									</el-button>
									<el-button
										class="iconfont iconsearch"
										onClick={() => {
											for (let key in initParam) {
												initParam[key] = null;
											}
											// proTable.value.getTableList();
										}}
									>
										{proxy?.$t("common.btn.reset")}
									</el-button>
								</el-form-item>
							</el-form>
						</BaseSearchForm>
					)}
					<ProTable
						ref={proTable}
						title={buttonsList.value.length ? "" : proxy?.$t("gateway.tab_title.manage")}
						columns={columns}
						requestApi={getTableList}
						initParam={initParam}
						searchCol={5}
						custSearch
						onSearchCollapsed={val => {
							collapsedSearch.value = val;
						}}
						ignoreInit
						dataCallback={dataCallback}
					>
						{{
							"search-onlineStatus": () => {
								return (
									<el-select v-model={initParam.onlineStatus} style="width:100px">
										<el-option label="全部" value=""></el-option>
										<el-option label="在线" value={DeviceStatusEnum.ONLINE}></el-option>
										<el-option label="离线" value={DeviceStatusEnum.OFFLINE}></el-option>
									</el-select>
								);
							},
							"search-deptName": () => {
								return <SelectDeptList detail={initParam} appendChild onChange={val => (initParam.deptId = val.id)} />;
							},
							tableHeader: (scope: any) => {
								return (
									<>
										{buttonsList.value?.map((item: any) => {
											return (
												<el-button onClick={() => clickBtn(item.path, scope)} type={item.btnClass}>
													<i class={`iconfont ${item.icon}`}></i>
													{item.menuName}
												</el-button>
											);
										})}
										{
											<el-dropdown
												trigger="click"
												v-slots={{
													dropdown: () => {
														return (
															<el-dropdown-menu>
																{btnOperateList.value.map((item: any) => {
																	return (
																		<>
																			<el-dropdown-item onClick={() => clickBtn(item.path, scope)}>
																				{item.menuName}
																			</el-dropdown-item>
																		</>
																	);
																})}
															</el-dropdown-menu>
														);
													}
												}}
											>
												<el-button type="primary" plain>
													{proxy?.$t("device_variable.btn.maintenance")}
													<span class="iconfont iconchevron-down pl-1"></span>
												</el-button>
											</el-dropdown>
										}
									</>
								);
							},
							sn: (scope: any) => {
								return (
									<div
										class="truncate cursor-pointer primary-color"
										title={proxy?.$t("gateway.line_title.sn")}
										onClick={() => clickBtn("details", scope)}
									>
										{scope.row.sn}
									</div>
								);
							},
							productModel: (scope: any) => {
								return scope.row.productModel ? (
									<div
										title={proxy?.$t("gateway.line_title.productModel")}
										class="truncate cursor-pointer primary-color"
										onClick={() => gotoPage(RouterPath.productDetail, { productModel: scope.row.productModel })}
									>
										{scope.row.productModel}
									</div>
								) : (
									"--"
								);
							},
							type: (scope: any) => {
								return DeviceType[scope.row.type] || "--";
							},
							location: (scope: any) => {
								return (
									<div
										title={proxy?.$t("gateway.line_title.location")}
										class="truncate cursor-pointer primary-color"
										onClick={() => clickBtn("updateLocation", scope)}
									>
										{scope.row.location?.address || "--"}
									</div>
								);
							},
							lastLiveTime: (scope: any) => {
								return dataFormat("datetime", scope.row.lastLiveTime);
							},
							logoutTime: (scope: any) => {
								return dataFormat("datetime", scope.row.logoutTime);
							},
							onlineStatus: (scope: any) => {
								return <OnlineStatus v-model={scope.row.onlineStatus} />;
							},
							operation: (scope: any) => {
								return (
									<>
										{buttonsList.value
											.filter((item: any) => item.path == "del")
											.map((item: any) => {
												return (
													<el-popconfirm
														title={proxy?.$t("gateway.confirm_title.del")}
														popper-class="jsonform-tooltip"
														onConfirm={() => submitDel({ idSn: scope.row.sn })}
													>
														{{
															reference: () => {
																return (
																	<el-link type="danger">
																		<i class="iconfont icontrash-2"></i>
																		{item.menuName}
																	</el-link>
																);
															}
														}}
													</el-popconfirm>
												);
											})}
										{!buttonsList.value.find((item: any) => item.path == "del") ? (
											<el-link type="danger" disabled>
												<i class="iconfont icontrash-2"></i>
												{proxy?.$t("gateway.operate.delete")}
											</el-link>
										) : null}
										<el-link
											type="primary"
											link
											class="iconfont iconbx-file"
											onClick={() => {
												clickBtn("details", scope);
											}}
										>
											{proxy?.$t("gateway.operate.detail")}
										</el-link>
									</>
								);
							},
							empty: () => {
								return (
									<div>
										<Empty
											class="text-left leading-6"
											subtitle={proxy?.$t("gateway.empty.subtitle")}
											btnText={proxy?.$t("gateway.empty.btnText")}
											onAdd={(scope: any) => {
												clickBtn("add", scope);
											}}
										/>
									</div>
								);
							}
						}}
					</ProTable>
				</div>
			);
		};
	}
});
